package com.conselheiro.web.persistence.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;

import org.apache.log4j.Logger;

import com.conselheiro.web.entidade.Identificavel;

public abstract class DAO<T extends Identificavel> {

	private Logger logger = Logger.getLogger(getClass());

	public void adicionar(T novo, EntityManager entityManager) {
		EntityTransaction transaction = entityManager.getTransaction();
		transaction.begin();
		entityManager.persist(novo);
		transaction.commit();
		logger.info("Entidade salva com sucesso: " + novo);
	}

	public void atualizar(T novo, EntityManager entityManager) {
		EntityTransaction transaction = entityManager.getTransaction();
		transaction.begin();
		entityManager.merge(novo);
		transaction.commit();
		logger.info("Entidade atualizada com sucesso: " + novo);
	}

	public void remover(T t, EntityManager entityManager) {
		remover(t.getId(), entityManager);
		logger.info("Entidade removida com sucesso: " + t);
	}

	public void remover(long id, EntityManager entityManager) {
		EntityTransaction transaction = entityManager.getTransaction();
		transaction.begin();
		entityManager.remove(entityManager.find(getClasse(), id));
		transaction.commit();
	}

	public List<T> recuperar(EntityManager entityManager) {
		return recuperar(true, entityManager);
	}

	public List<T> recuperar(boolean desc, EntityManager entityManager) {
		return recuperar(0, -1, desc, entityManager);
	}

	@SuppressWarnings("unchecked")
	public List<T> recuperar(int firstResult, int maxResults, boolean desc,
			EntityManager entityManager) {
		String order = desc ? "desc" : "asc";
		Query query = entityManager.createQuery("select o from "
				+ getClasse().getSimpleName() + " o order by o.id " + order);

		if (firstResult >= 0 && maxResults >= 0) {
			query.setFirstResult(firstResult);
			query.setMaxResults(maxResults);
		}
		return query.getResultList();
	}

	public T recuperar(long id, EntityManager entityManager) {
		return entityManager.find(getClasse(), id);
	}
	
	protected abstract Class<T> getClasse();

}
